<!DOCTYPE html>
<html>
<head>
    <title>Thermodynamic System Diagram</title>
    <style>
        body { margin: 20px; text-align: center; }
        canvas { border: 1px solid #ccc; }
    </style>
</head>
<body>

<canvas id="physicsCanvas" width="650" height="400"></canvas>

<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // Clear canvas
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // --- General settings ---
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;
    ctx.font = "24px Arial";
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';

    // --- Dimensions and derived positions ---
    const startY = 100;
    const heightA = 140;

    // Piston F Assembly
    const rodLength = 60;
    const rodHeight = 12;
    const pistonHeadWidth = 10;
    const rodStartX = 80;

    const rodX = rodStartX;
    const rodY = startY + heightA / 2 - rodHeight / 2;

    const pistonHeadX = rodX + rodLength;
    const pistonHeadY = startY;

    // Container A
    const widthA = 220;
    const containerAx = pistonHeadX;
    const containerAy = startY;

    // --- Drawing Piston F Assembly ---

    // 1. Piston Rod
    ctx.beginPath();
    ctx.rect(rodX, rodY, rodLength, rodHeight);
    ctx.stroke();
    // Hatching for Piston Rod (diagonal lines) using clipping
    ctx.save();
    ctx.beginPath();
    ctx.rect(rodX, rodY, rodLength, rodHeight);
    ctx.clip();
    ctx.lineWidth = 1;
    ctx.beginPath();
    const hatchSpacing = 6;
    for (let i = -rodHeight; i < rodLength; i += hatchSpacing) {
        ctx.moveTo(rodX + i, rodY);
        ctx.lineTo(rodX + i + rodHeight, rodY + rodHeight);
    }
    ctx.stroke();
    ctx.restore();

    // 2. Piston Head
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.rect(pistonHeadX, pistonHeadY, pistonHeadWidth, heightA);
    ctx.stroke();
    // Hatching for Piston Head (vertical lines)
    ctx.lineWidth = 1;
    ctx.beginPath();
    for (let x_hatch = pistonHeadX + 3; x_hatch < pistonHeadX + pistonHeadWidth; x_hatch += 3) {
        ctx.moveTo(x_hatch, pistonHeadY);
        ctx.lineTo(x_hatch, pistonHeadY + heightA);
    }
    ctx.stroke();

    // 3. Label F
    ctx.lineWidth = 2;
    ctx.fillText('F', rodX + rodLength / 2, rodY + rodHeight + 30);


    // --- Drawing Container A ---
    ctx.beginPath();
    ctx.rect(containerAx, containerAy, widthA, heightA);
    ctx.stroke();

    // Gas particles in A
    const gasStartX = containerAx + pistonHeadWidth;
    const gasWidth = widthA - pistonHeadWidth;
    ctx.fillStyle = 'black';
    const numDots = 700;
    for (let i = 0; i < numDots; i++) {
        const x = gasStartX + 5 + Math.random() * (gasWidth - 10);
        const y = containerAy + 5 + Math.random() * (heightA - 10);
        ctx.beginPath();
        ctx.arc(x, y, 1.2, 0, 2 * Math.PI);
        ctx.fill();
    }

    // Label A
    ctx.fillText('A', containerAx + widthA / 2, containerAy - 20);

    // --- Drawing Connection and Container B ---

    // Connecting Tube
    const tubeGap = 80;
    const tubeThickness = 4;
    const tubeY_center = containerAy + heightA / 2;
    const tubeStartX = containerAx + widthA;
    const tubeEndX = tubeStartX + tubeGap;

    ctx.beginPath();
    ctx.moveTo(tubeStartX, tubeY_center - tubeThickness / 2);
    ctx.lineTo(tubeEndX, tubeY_center - tubeThickness / 2);
    ctx.moveTo(tubeStartX, tubeY_center + tubeThickness / 2);
    ctx.lineTo(tubeEndX, tubeY_center + tubeThickness / 2);
    ctx.stroke();

    // Valve K
    const valveX = tubeStartX + tubeGap / 2;
    const valveSize = 30;
    ctx.beginPath();
    ctx.moveTo(valveX, tubeY_center - valveSize / 2);
    ctx.lineTo(valveX, tubeY_center + valveSize / 2);
    ctx.moveTo(valveX - valveSize / 2, tubeY_center);
    ctx.lineTo(valveX + valveSize / 2, tubeY_center);
    ctx.stroke();

    // Label K
    ctx.fillText('K', valveX, tubeY_center - valveSize / 2 - 10);

    // Container B
    const widthB = 180;
    const heightB = 160;
    const rectBx = tubeEndX;
    const rectBy = tubeY_center - heightB / 2;
    ctx.beginPath();
    ctx.rect(rectBx, rectBy, widthB, heightB);
    ctx.stroke();

    // Label B
    ctx.fillText('B', rectBx + widthB / 2, rectBy - 20);

    // --- Drawing Caption ---
    ctx.font = "24px 'KaiTi', 'SimSun'";
    ctx.fillText('热图 2.9.1', canvas.width / 2, containerAy + heightA + 80);

</script>

</body>
</html>